package com.ali.service.impl;

import com.ali.api.PayApi;
import com.ali.common.Response;
import com.ali.common.ReturnEnum;
import com.ali.common.ServerName;
import com.ali.service.Resilience4jService;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public class Resilience4jServiceImpl implements Resilience4jService {
    @Resource
    private PayApi payApi;

    @CircuitBreaker(name = ServerName.PAY, fallbackMethod = "myCircuitBreakerFallBack")
    @Override
    public Response<String> circuitBreaker(Map<String, Object> param) {
        return payApi.control(param);
    }

    /**
     * 服务熔断，服务降级方法
     */
    public Response<String> myCircuitBreakerFallBack(Map<String, Object> param, Throwable t) {
        return Response.fail(ReturnEnum.RC999.getCode(), "服务降级，请稍后再试：" + param);
    }

    @Bulkhead(name = ServerName.PAY, fallbackMethod = "myBulkheadSemaphoreFallBack", type = Bulkhead.Type.SEMAPHORE)
    @Override
    public Response<String> bulkheadSemaphore(Map<String, Object> param) {
        return payApi.control(param);
    }

    /**
     * 服务隔离，信号量模式，服务降级方法
     */
    public Response<String> myBulkheadSemaphoreFallBack(Map<String, Object> param, Throwable t) {
        return Response.fail(ReturnEnum.RC999.getCode(), "服务降级，请稍后再试：" + param);
    }

    @Bulkhead(name = ServerName.PAY, fallbackMethod = "myBulkheadThreadPoolFallBack", type = Bulkhead.Type.THREADPOOL)
    @Override
    public CompletableFuture<String> bulkheadThreadPool(Map<String, Object> param) {
        return CompletableFuture.supplyAsync(() -> payApi.control(param).toString());
    }

    /**
     * 服务隔离，线程池模式，服务降级方法
     */
    public CompletableFuture<String> myBulkheadThreadPoolFallBack(Map<String, Object> param, Throwable t) {
        return CompletableFuture.supplyAsync(() -> Response.fail(ReturnEnum.RC999.getCode(), "服务降级，请稍后再试：" + param).toString());
    }

    @RateLimiter(name = ServerName.PAY, fallbackMethod = "myRateLimiterFallBack")
    @Override
    public Response<String> rateLimiter(Map<String, Object> param) {
        return payApi.control(param);
    }

    /**
     * Resilience4j服务限流，服务降级方法
     */
    public Response<String> myRateLimiterFallBack(Map<String, Object> param, Throwable t) {
        return Response.fail(ReturnEnum.RC999.getCode(), "服务降级，请稍后再试：" + param);
    }
}